﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Cb按钮生按钮按钮无穷尽
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            this.InitializeComponent();
        }

#warning Cb-1：在这里！
        /*
         * 在本项目中，你可以了解到：
         * 如何创建按钮，使用代码进行事件绑定
         */
        private void CreateButton(object sender, EventArgs e)
        {
            /*
             * 这被称为强制转换。
             * 一般而言，我们规定，在事件触发时，传递给各个方法的 sender 就是触发者。
             * 由于这个方法肯定是被绑定在某个按钮，我们就做了如此的转换。
             * 
             * 请注意， sender 变量的类型不会改变，仍为 object 类型。
             * 
             * 请注意，这和先前的 string 与 int 的相互转换并不相同，
             * 它并不创建一个新的按钮，此时的 sender 和 senderButton 都储存着同一个按钮。
             * 等到了解到类的继承和运算符重载时，我们会再详细讨论这个问题。
             * 
             * 如果运行期间发现 sender 并不是一个按钮，这句语句会抛出异常。
             */
            var senderButton = (Button)sender;
            /*
             * 新建一个按钮。
             * 换一个说法：实例化 Button 类型，产生一个 Button 类型的对象。
             */
            var button = new Button();
            /*
             * 在刚刚创建的按钮的 Click 事件上绑定 CreateButton 方法。
             * 我们使用 += 和 -= 来进行事件的绑定与解绑。
             * 
             * 因为是绑定方法本身，而不是在此时调用方法，所以不使用小括号。
             */
            button.Click += CreateButton;
            /*
             * this 译为“这个”。
             * 而我们这段代码是写在 Form1 中的，
             * 因此这句话表示：在 这个窗体 的 控件列表（Controls） 中添加上述按钮。
             * 
             * 如果不会产生歧义， this 常常可以省略。
             * 
             * 在控件列表中的控件，才会被显示到界面上。
             */
            this.Controls.Add(button);

            /*
             * location 译为“位置”。
             */
            button.Location = new Point(senderButton.Location.X + 100, senderButton.Location.Y);

            /*
             * 您可以发现，我们其实并不要求控件具有 (Name) ，
             * (Name) 的设计只是方便与设计器进行交互。
             * 
             * 读到这里，您可能对设计器产生一些疑问。
             * 实际上，设计器的做的工作只是代码生成，
             * 设计器生成的代码位于 Form1.Designer.cs ，
             * 您可以前往了解，或许有更多的收获。
             */
        }
    }
}
